Skip to content

JS 中有哪些方法可以实现继承

ES6

js
class Animate {
  constructor() {
    this.type = "animate";
  }
}
class Cat extends Animate {
  constructor() {
    super();
    this.name = "cat";
  }
}
Cat.__proto__ === Animate; //继承属性
Cat.prototype.__proto__ == Animate.prototype; //继承方法

console.log(new Cat());
js
function Animate() {
  this.type = 'animate'
}
Animate.prototype.getType = function() { return this.name }

function Cat() {
  Animate.call(this)
  this.name = 'cat'
}
extends(Cat, Animate);

function extends = (child, parent) {
  child.prototype = Object.create(parent);
  child.prototype.constructor = child;
}
Cat.prototype.getName = function() { return this.name }

console.log(new Cat())

ES5

  • call

    只继承属性,父原型方法调不了

js
function Animate() {
  this.type = "animate";
}

function Cat() {
  this.name = "cat";
  Animate.call(this); // Animate.prototype 的原型方法调用不了
}

console.log(new Cat());
  • 原型链继承
js
function Animate() {
  this.type = "animate";
}

function Cat() {
  this.name = "cat";
}

Cat.prototype = new Animate(); // 实例共用 Animate 属性,一改全改
Cat.prototype.constructor = Cat;
console.log(new Cat());
  • 组合模式-寄生
js
function Animate() {
  this.type = "animate";
}
Animate.prototype.getAnimate = function () {
  console.log("getAnimate");
};

function Cat() {
  this.name = "cat";
  Animate.call(this, name);
}

Cat.prototype = Object.create(Animate.prototype); // 这种 Animate 原型方法会在父级
Cat.prototype.getCat = function () {
  console.log("getCat");
};

// Cat.prototype = new Animate() // 会多一个 Animate 属性

// Cat.prototype = Animate.prototype // 这种  Cat.prototype  自己方法需要写到,这一行下面,Animate 原型方法跟 Cat 在同一级

Cat.prototype.constructor = Cat;

console.log(new Cat());

原型链

构造函数有 proto 指向 Function.prototype

js
function Animate() {
  this.name = "animate";
}
const cat = new Animate();

cat.__proto__ === Animate.prototype;
Animate.prototype.constructor === Animate;
Object.prototype.__proto__ === null;
Animate.__proto__ === Function.prototype;

function Object(a, b) {
  return a + b;
}
var add = new Function("a", "b", "return a+b");
Object.__proto__ = Function.prototype;
Function.__proto__ = Function.prototype;
Function.__proto__ === Object.__proto__;

Object.create

js
function create(prototype) {
  function fn() {}
  fn.prototype = prototype;
  return new fn();
}

ES5 和 ES6 继承区别

  • ES6 需要 在子类调用 super 放可获得父类私有属性
  • 默认严格模式、不存在变量提升、方法不可以枚举

在 MIT 许可下发布